package it.michaellinker.msr.web.util.metric.counter;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Boolean value counter.
 * Starts counting the first value that comes in and all the opposite ones.
 *
 * @param <T> The type of object to count.
 */
public class BooleanCounter<T> implements RequestCounter<T> {
    private static final long COUNTER_INITIAL_VALUE = 0L;
    private final T trueValue;
    private final T falseValue;
    private final AtomicLong trueCounter = new AtomicLong(COUNTER_INITIAL_VALUE);
    private final AtomicLong falseCounter = new AtomicLong(COUNTER_INITIAL_VALUE);

    public BooleanCounter(T trueValue, T falseValue) {
        this.trueValue = trueValue;
        this.falseValue = falseValue;
    }

    @Override
    public void count(T key) {
        if (key.equals(trueValue)) {
            trueCounter.incrementAndGet();
        }
        if (key.equals(falseValue)) {
            falseCounter.incrementAndGet();
        }
    }

    @Override
    public Map<T, Long> getResult() {
        Map<T, Long> bufferCounterMap = new HashMap<>();

        this.saveResultToMap(trueValue, trueCounter, bufferCounterMap);
        this.saveResultToMap(falseValue, falseCounter, bufferCounterMap);

        return bufferCounterMap;
    }

    private void saveResultToMap(T key, AtomicLong counter, Map<T, Long> map) {
        map.put(key, counter.getAndSet(COUNTER_INITIAL_VALUE));
    }
}
